import React, { useState, useEffect } from 'react';
import {
  Dialog as MuiDialog,
  Button,
  DialogActions,
  DialogContent,
  DialogTitle,
  Box,
} from '@mui/material';
import { useAppSelector, useAppDispatch } from '../../../redux/hooks';
import { closeBackendErrorDialog } from '../../../redux/slices/errorsSlice';
import { pythonCall } from '../../../redux/slices/generalSlice';
import { bgDarkest, fontColor } from '../../../theme';

interface ActionDialogProps {
  open?: boolean;
  title?: string;
  buttonLabel?: string;
  message?: string;
  command?: string;
  args?: Record<string, any>;
  isFormValid?: () => boolean;
  callback?: (command: string, args: Record<string, any>) => void;
  onAction?: () => void;
  onRequestClose?: () => void;
  children?: React.ReactNode;
  [key: string]: any;
}

/**
 * ActionDialog Component
 * Base dialog component for performing actions (e.g., save, load, import)
 * Handles form validation, Python command execution, and error display
 */
const ActionDialog: React.FC<ActionDialogProps> = ({
  open = false,
  title = '',
  buttonLabel = 'OK',
  message = '',
  command,
  args = {},
  isFormValid,
  callback,
  onAction,
  onRequestClose,
  children,
  ...otherProps
}) => {
  const dispatch = useAppDispatch();
  const { errorMessage, errorDetails, openErrorDialogBox } = useAppSelector(
    (state) => state.errors,
  );
  const [hide, setHide] = useState(!openErrorDialogBox && !open);

  useEffect(() => {
    setHide(!openErrorDialogBox && !open);
  }, [openErrorDialogBox, open]);

  const handleClickGoBack = (): void => {
    setHide(true);
    clearErrorDialogBox();
  };

  const cancelDialog = (): void => {
    clearErrorDialogBox();
    setHide(true);
    if (onRequestClose) {
      onRequestClose();
    }
  };

  const performAction = (): void => {
    if (command) {
      if (isFormValid === undefined || isFormValid()) {
        if (callback) {
          callback(command, args);
        } else {
          // Execute Python command via Redux
          dispatch(pythonCall(command, args));
        }
      }
    }
    if (onAction) {
      onAction();
    }
    setHide(true);
    if (onRequestClose) {
      onRequestClose();
    }
  };

  const clearErrorDialogBox = (): void => {
    dispatch(closeBackendErrorDialog());
  };

  const shouldDisplay = Boolean(!hide || openErrorDialogBox);

  let action: React.ReactNode;
  let displayTitle: string;
  let content: React.ReactNode;

  if (!errorMessage || errorMessage === '') {
    displayTitle = title;
    action = (
      <>
        <Button onClick={cancelDialog} sx={{ mr: 1.25 }} key="CANCEL">
          CANCEL
        </Button>
        <Button
          id="appBarPerformActionButton"
          key="appBarPerformActionButton"
          variant="contained"
          color="primary"
          onClick={performAction}
        >
          {buttonLabel}
        </Button>
      </>
    );
    content = children;
  } else {
    action = (
      <Button
        variant="contained"
        color="primary"
        key="CLOSE"
        onClick={handleClickGoBack}
      >
        CLOSE
      </Button>
    );
    displayTitle = errorMessage;
    if (errorDetails) {
      content = (
        <Box
          component="pre"
          sx={{
            whiteSpace: 'pre-wrap',
            backgroundColor: bgDarkest,
            color: fontColor,
            p: 2,
            borderRadius: 1,
          }}
          dangerouslySetInnerHTML={{
            __html: (window as any).IPython?.utils?.fixConsole?.(errorDetails) || errorDetails,
          }}
        />
      );
    }
  }

  if (!shouldDisplay) {
    return null;
  }

  return (
    <MuiDialog
      fullWidth
      maxWidth={openErrorDialogBox ? 'md' : 'sm'}
      open={shouldDisplay}
      onClose={cancelDialog}
      {...otherProps}
    >
      <DialogTitle>{displayTitle}</DialogTitle>
      <DialogContent>{content}</DialogContent>
      <DialogActions>{action}</DialogActions>
    </MuiDialog>
  );
};

export default ActionDialog;

